home *** CD-ROM | disk | FTP | other *** search
/ Cre@te Online 2000 December / Cre@teOnline CD05.iso / MacSoft / XML ConsoleMax.sea / XML ConsoleMax / Required / swingall.jar / javax / swing / text / html / HTMLWriter.class (.txt) < prev    next >
Encoding:
Java Class File  |  1999-07-15  |  17.6 KB  |  1,098 lines

  1. package javax.swing.text.html;
  2.  
  3. import java.io.IOException;
  4. import java.io.Writer;
  5. import java.util.Enumeration;
  6. import java.util.Stack;
  7. import java.util.Vector;
  8. import javax.swing.DefaultComboBoxModel;
  9. import javax.swing.DefaultListModel;
  10. import javax.swing.text.AbstractDocument;
  11. import javax.swing.text.AbstractWriter;
  12. import javax.swing.text.AttributeSet;
  13. import javax.swing.text.BadLocationException;
  14. import javax.swing.text.Document;
  15. import javax.swing.text.Element;
  16. import javax.swing.text.ElementIterator;
  17. import javax.swing.text.MutableAttributeSet;
  18. import javax.swing.text.Segment;
  19. import javax.swing.text.SimpleAttributeSet;
  20. import javax.swing.text.Style;
  21. import javax.swing.text.StyleConstants;
  22. import javax.swing.text.StyleContext;
  23. import javax.swing.text.html.HTML.Attribute;
  24. import javax.swing.text.html.HTML.Tag;
  25.  
  26. public class HTMLWriter extends AbstractWriter {
  27.    private Stack blockElementStack;
  28.    private boolean inContent;
  29.    private boolean inPre;
  30.    private int preEndOffset;
  31.    private boolean inTextArea;
  32.    private boolean newlineOutputed;
  33.    private boolean completeDoc;
  34.    private Vector tags;
  35.    private Vector tagValues;
  36.    private char[] tempChars;
  37.    private char[] indentChars;
  38.    private Segment segment;
  39.    private Vector tagsToRemove;
  40.    private boolean wroteHead;
  41.    private Writer out;
  42.    private int maxLineLength;
  43.    private int currLength;
  44.    private int indentLevel;
  45.    private int indentSpace;
  46.    private int offsetIndent;
  47.    private String newline;
  48.    private boolean isLineEmpty;
  49.    private int startOffset;
  50.    private int endOffset;
  51.    private boolean indentNext;
  52.    private boolean writeCSS;
  53.    private MutableAttributeSet convAttr;
  54.    private MutableAttributeSet oConvAttr;
  55.  
  56.    public HTMLWriter(Writer var1, HTMLDocument var2) {
  57.       this(var1, var2, 0, ((AbstractDocument)var2).getLength());
  58.    }
  59.  
  60.    public HTMLWriter(Writer var1, HTMLDocument var2, int var3, int var4) {
  61.       super(var1, var2, var3, var4);
  62.       this.blockElementStack = new Stack();
  63.       this.inContent = false;
  64.       this.inPre = false;
  65.       this.inTextArea = false;
  66.       this.newlineOutputed = false;
  67.       this.tags = new Vector(10);
  68.       this.tagValues = new Vector(10);
  69.       this.tagsToRemove = new Vector(10);
  70.       this.maxLineLength = 80;
  71.       this.indentLevel = 0;
  72.       this.indentSpace = 2;
  73.       this.offsetIndent = 0;
  74.       this.indentNext = false;
  75.       this.writeCSS = false;
  76.       this.convAttr = new SimpleAttributeSet();
  77.       this.oConvAttr = new SimpleAttributeSet();
  78.       this.completeDoc = var3 == 0 && var4 == ((AbstractDocument)var2).getLength();
  79.       this.maxLineLength = 80;
  80.       this.out = var1;
  81.       Object var5 = ((AbstractDocument)var2).getProperty("__EndOfLine__");
  82.       if (var5 instanceof String) {
  83.          this.newline = (String)var5;
  84.       } else {
  85.          try {
  86.             this.newline = System.getProperty("line.separator");
  87.          } catch (SecurityException var6) {
  88.          }
  89.  
  90.          if (this.newline == null) {
  91.             this.newline = "\n";
  92.          }
  93.       }
  94.  
  95.       this.startOffset = var3;
  96.       this.endOffset = var3 + var4;
  97.    }
  98.  
  99.    protected void closeOutUnwantedEmbeddedTags(AttributeSet var1) throws IOException {
  100.       this.tagsToRemove.removeAllElements();
  101.       var1 = this.convertToHTML(var1, (MutableAttributeSet)null);
  102.       int var4 = -1;
  103.       int var5 = this.tags.size();
  104.  
  105.       for(int var6 = var5 - 1; var6 >= 0; --var6) {
  106.          HTML.Tag var2 = (HTML.Tag)this.tags.elementAt(var6);
  107.          Object var3 = this.tagValues.elementAt(var6);
  108.          if (var1 == null || this.noMatchForTagInAttributes(var1, var2, var3)) {
  109.             var4 = var6;
  110.             this.tagsToRemove.addElement(var2);
  111.          }
  112.       }
  113.  
  114.       if (var4 != -1) {
  115.          boolean var7 = var5 - var4 == this.tagsToRemove.size();
  116.  
  117.          for(int var8 = var5 - 1; var8 >= var4; --var8) {
  118.             HTML.Tag var12 = (HTML.Tag)this.tags.elementAt(var8);
  119.             if (var7 || this.tagsToRemove.contains(var12)) {
  120.                this.tags.removeElementAt(var8);
  121.                this.tagValues.removeElementAt(var8);
  122.             }
  123.  
  124.             this.write('<');
  125.             this.write('/');
  126.             this.write(var12.toString());
  127.             this.write('>');
  128.          }
  129.  
  130.          var5 = this.tags.size();
  131.  
  132.          for(int var9 = var4; var9 < var5; ++var9) {
  133.             HTML.Tag var13 = (HTML.Tag)this.tags.elementAt(var9);
  134.             this.write('<');
  135.             this.write(var13.toString());
  136.             Object var10 = this.tagValues.elementAt(var9);
  137.             if (var10 != null && var10 instanceof AttributeSet) {
  138.                this.writeAttributes((AttributeSet)var10);
  139.             }
  140.  
  141.             this.write('>');
  142.          }
  143.       }
  144.  
  145.    }
  146.  
  147.    protected void comment(Element var1) throws BadLocationException, IOException {
  148.       AttributeSet var2 = var1.getAttributes();
  149.       if (this.matchNameAttribute(var2, Tag.COMMENT)) {
  150.          Object var3 = var2.getAttribute(Attribute.COMMENT);
  151.          if (var3 instanceof String) {
  152.             this.writeComment((String)var3);
  153.          } else {
  154.             this.writeComment((String)null);
  155.          }
  156.       }
  157.  
  158.    }
  159.  
  160.    AttributeSet convertToHTML(AttributeSet var1, MutableAttributeSet var2) {
  161.       if (var2 == null) {
  162.          var2 = this.convAttr;
  163.       }
  164.  
  165.       var2.removeAttributes(var2);
  166.       if (this.writeCSS) {
  167.          convertToHTML40(var1, var2);
  168.       } else {
  169.          convertToHTML32(var1, var2);
  170.       }
  171.  
  172.       return var2;
  173.    }
  174.  
  175.    private static void convertToHTML32(AttributeSet var0, MutableAttributeSet var1) {
  176.       if (var0 != null) {
  177.          Enumeration var2 = var0.getAttributeNames();
  178.          String var3 = "";
  179.  
  180.          while(var2.hasMoreElements()) {
  181.             Object var4 = var2.nextElement();
  182.             if (var4 instanceof CSS.Attribute) {
  183.                if (var4 != javax.swing.text.html.CSS.Attribute.FONT_FAMILY && var4 != javax.swing.text.html.CSS.Attribute.FONT_SIZE && var4 != javax.swing.text.html.CSS.Attribute.COLOR) {
  184.                   if (var4 == javax.swing.text.html.CSS.Attribute.FONT_WEIGHT) {
  185.                      CSS.FontWeight var5 = (CSS.FontWeight)var0.getAttribute(javax.swing.text.html.CSS.Attribute.FONT_WEIGHT);
  186.                      if (var5 != null && var5.getValue() > 400) {
  187.                         var1.addAttribute(Tag.B, SimpleAttributeSet.EMPTY);
  188.                      }
  189.                   } else if (var4 == javax.swing.text.html.CSS.Attribute.FONT_STYLE) {
  190.                      String var6 = var0.getAttribute(var4).toString();
  191.                      if (var6.indexOf("italic") >= 0) {
  192.                         var1.addAttribute(Tag.I, SimpleAttributeSet.EMPTY);
  193.                      }
  194.                   } else if (var4 == javax.swing.text.html.CSS.Attribute.TEXT_DECORATION) {
  195.                      String var7 = var0.getAttribute(var4).toString();
  196.                      if (var7.indexOf("underline") >= 0) {
  197.                         var1.addAttribute(Tag.U, SimpleAttributeSet.EMPTY);
  198.                      }
  199.  
  200.                      if (var7.indexOf("line-through") >= 0) {
  201.                         var1.addAttribute(Tag.STRIKE, SimpleAttributeSet.EMPTY);
  202.                      }
  203.                   } else if (var4 == javax.swing.text.html.CSS.Attribute.VERTICAL_ALIGN) {
  204.                      String var8 = var0.getAttribute(var4).toString();
  205.                      if (var8.indexOf("sup") >= 0) {
  206.                         var1.addAttribute(Tag.SUP, SimpleAttributeSet.EMPTY);
  207.                      }
  208.  
  209.                      if (var8.indexOf("sub") >= 0) {
  210.                         var1.addAttribute(Tag.SUB, SimpleAttributeSet.EMPTY);
  211.                      }
  212.                   } else if (var4 == javax.swing.text.html.CSS.Attribute.TEXT_ALIGN) {
  213.                      var1.addAttribute(Attribute.ALIGN, var0.getAttribute(var4).toString());
  214.                   } else {
  215.                      if (var3.length() > 0) {
  216.                         var3 = var3 + "; ";
  217.                      }
  218.  
  219.                      var3 = var3 + var4 + ": " + var0.getAttribute(var4);
  220.                   }
  221.                } else {
  222.                   createFontAttribute((CSS.Attribute)var4, var0, var1);
  223.                }
  224.             } else {
  225.                var1.addAttribute(var4, var0.getAttribute(var4));
  226.             }
  227.          }
  228.  
  229.          if (var3.length() > 0) {
  230.             var1.addAttribute(Attribute.STYLE, var3);
  231.          }
  232.  
  233.       }
  234.    }
  235.  
  236.    private static void convertToHTML40(AttributeSet var0, MutableAttributeSet var1) {
  237.       Enumeration var2 = var0.getAttributeNames();
  238.       String var3 = "";
  239.  
  240.       while(var2.hasMoreElements()) {
  241.          Object var4 = var2.nextElement();
  242.          if (var4 instanceof CSS.Attribute) {
  243.             var3 = var3 + " " + var4 + "=" + var0.getAttribute(var4) + ";";
  244.          } else {
  245.             var1.addAttribute(var4, var0.getAttribute(var4));
  246.          }
  247.       }
  248.  
  249.       if (var3.length() > 0) {
  250.          var1.addAttribute(Attribute.STYLE, var3);
  251.       }
  252.  
  253.    }
  254.  
  255.    private static void createFontAttribute(CSS.Attribute var0, AttributeSet var1, MutableAttributeSet var2) {
  256.       Object var3 = (MutableAttributeSet)var2.getAttribute(Tag.FONT);
  257.       if (var3 == null) {
  258.          var3 = new SimpleAttributeSet();
  259.          var2.addAttribute(Tag.FONT, var3);
  260.       }
  261.  
  262.       String var4 = var1.getAttribute(var0).toString();
  263.       if (var0 == javax.swing.text.html.CSS.Attribute.FONT_FAMILY) {
  264.          ((MutableAttributeSet)var3).addAttribute(Attribute.FACE, var4);
  265.       } else if (var0 == javax.swing.text.html.CSS.Attribute.FONT_SIZE) {
  266.          ((MutableAttributeSet)var3).addAttribute(Attribute.SIZE, var4);
  267.       } else if (var0 == javax.swing.text.html.CSS.Attribute.COLOR) {
  268.          ((MutableAttributeSet)var3).addAttribute(Attribute.COLOR, var4);
  269.       }
  270.  
  271.    }
  272.  
  273.    protected void decrIndent() {
  274.       if (this.offsetIndent > 0) {
  275.          --this.offsetIndent;
  276.       } else {
  277.          --this.indentLevel;
  278.       }
  279.  
  280.    }
  281.  
  282.    protected void emptyTag(Element var1) throws BadLocationException, IOException {
  283.       if (!this.inContent && !this.inPre) {
  284.          this.indent();
  285.       }
  286.  
  287.       AttributeSet var2 = var1.getAttributes();
  288.       this.closeOutUnwantedEmbeddedTags(var2);
  289.       this.writeEmbeddedTags(var2);
  290.       if (this.matchNameAttribute(var2, Tag.CONTENT)) {
  291.          this.inContent = true;
  292.          this.text(var1);
  293.       } else if (this.matchNameAttribute(var2, Tag.COMMENT)) {
  294.          this.comment(var1);
  295.       } else {
  296.          boolean var3 = this.isBlockTag(var1.getAttributes());
  297.          if (this.inContent && var3) {
  298.             this.writeNewline();
  299.             this.indent();
  300.          }
  301.  
  302.          Object var4 = var2 != null ? var2.getAttribute(StyleConstants.NameAttribute) : null;
  303.          Object var5 = var2 != null ? var2.getAttribute(Attribute.ENDTAG) : null;
  304.          boolean var6 = false;
  305.          if (var4 != null && var5 != null && var5 instanceof String && ((String)var5).equals("true")) {
  306.             var6 = true;
  307.          }
  308.  
  309.          if (this.completeDoc && this.matchNameAttribute(var2, Tag.HEAD)) {
  310.             if (var6) {
  311.                this.writeStyles(((HTMLDocument)((AbstractWriter)this).getDocument()).getStyleSheet());
  312.             }
  313.  
  314.             this.wroteHead = true;
  315.          }
  316.  
  317.          this.write('<');
  318.          if (var6) {
  319.             this.write('/');
  320.          }
  321.  
  322.          this.write(var1.getName());
  323.          this.writeAttributes(var2);
  324.          this.write('>');
  325.          if (this.matchNameAttribute(var2, Tag.TITLE) && !var6) {
  326.             Document var7 = var1.getDocument();
  327.             String var8 = (String)var7.getProperty("title");
  328.             this.write(var8);
  329.          } else if (!this.inContent || var3) {
  330.             this.writeNewline();
  331.             if (var3 && this.inContent) {
  332.                this.indent();
  333.             }
  334.          }
  335.       }
  336.  
  337.    }
  338.  
  339.    protected void endTag(Element var1) throws IOException {
  340.       if (!this.synthesizedElement(var1)) {
  341.          if (this.matchNameAttribute(var1.getAttributes(), Tag.PRE)) {
  342.             this.inPre = false;
  343.          }
  344.  
  345.          this.closeOutUnwantedEmbeddedTags(var1.getAttributes());
  346.          if (this.inContent) {
  347.             if (!this.newlineOutputed) {
  348.                this.writeNewline();
  349.             }
  350.  
  351.             this.newlineOutputed = false;
  352.             this.inContent = false;
  353.          }
  354.  
  355.          this.indent();
  356.          this.write('<');
  357.          this.write('/');
  358.          this.write(var1.getName());
  359.          this.write('>');
  360.          this.writeNewline();
  361.       }
  362.    }
  363.  
  364.    protected void incrIndent() {
  365.       if (this.offsetIndent > 0) {
  366.          ++this.offsetIndent;
  367.       } else if (++this.indentLevel * this.indentSpace >= this.maxLineLength) {
  368.          ++this.offsetIndent;
  369.          --this.indentLevel;
  370.       }
  371.  
  372.    }
  373.  
  374.    protected void indent() throws IOException {
  375.       int var1 = this.indentLevel * this.indentSpace;
  376.       if (this.indentChars == null || var1 > this.indentChars.length) {
  377.          this.indentChars = new char[var1];
  378.  
  379.          for(int var2 = 0; var2 < var1; ++var2) {
  380.             this.indentChars[var2] = ' ';
  381.          }
  382.       }
  383.  
  384.       this.out.write(this.indentChars, 0, var1);
  385.       this.currLength += var1;
  386.    }
  387.  
  388.    private boolean indentNeedsIncrementing(Element var1, Element var2) {
  389.       if (var2.getParentElement() == var1 && !this.inPre) {
  390.          if (this.indentNext) {
  391.             this.indentNext = false;
  392.             return true;
  393.          }
  394.  
  395.          if (this.synthesizedElement(var2)) {
  396.             this.indentNext = true;
  397.          } else if (!this.synthesizedElement(var1)) {
  398.             return true;
  399.          }
  400.       }
  401.  
  402.       return false;
  403.    }
  404.  
  405.    private int indexOf(char[] var1, char var2, int var3, int var4) {
  406.       while(var3 < var4) {
  407.          if (var1[var3] == var2) {
  408.             return var3;
  409.          }
  410.  
  411.          ++var3;
  412.       }
  413.  
  414.       return -1;
  415.    }
  416.  
  417.    protected boolean isBlockTag(AttributeSet var1) {
  418.       Object var2 = var1.getAttribute(StyleConstants.NameAttribute);
  419.       if (var2 instanceof HTML.Tag) {
  420.          HTML.Tag var3 = (HTML.Tag)var2;
  421.          return var3.isBlock();
  422.       } else {
  423.          return false;
  424.       }
  425.    }
  426.  
  427.    private boolean isFormElementWithContent(AttributeSet var1) {
  428.       return this.matchNameAttribute(var1, Tag.TEXTAREA) || this.matchNameAttribute(var1, Tag.SELECT);
  429.    }
  430.  
  431.    protected boolean matchNameAttribute(AttributeSet var1, HTML.Tag var2) {
  432.       Object var3 = var1.getAttribute(StyleConstants.NameAttribute);
  433.       if (var3 instanceof HTML.Tag) {
  434.          HTML.Tag var4 = (HTML.Tag)var3;
  435.          if (var4 == var2) {
  436.             return true;
  437.          }
  438.       }
  439.  
  440.       return false;
  441.    }
  442.  
  443.    private boolean noMatchForTagInAttributes(AttributeSet var1, HTML.Tag var2, Object var3) {
  444.       if (var1 != null && var1.isDefined(var2)) {
  445.          Object var4 = var1.getAttribute(var2);
  446.          boolean var10000;
  447.          if (var3 == null) {
  448.             if (var4 == null) {
  449.                return false;
  450.             }
  451.  
  452.             var10000 = false;
  453.          } else {
  454.             if (var4 != null && var3.equals(var4)) {
  455.                return false;
  456.             }
  457.  
  458.             var10000 = false;
  459.          }
  460.  
  461.          if (var10000) {
  462.             return false;
  463.          }
  464.       }
  465.  
  466.       return true;
  467.    }
  468.  
  469.    protected void selectContent(AttributeSet var1) throws IOException {
  470.       Object var2 = var1.getAttribute(StyleConstants.ModelAttribute);
  471.       this.incrIndent();
  472.       if (var2 instanceof OptionListModel) {
  473.          OptionListModel var3 = (OptionListModel)var2;
  474.          int var4 = ((DefaultListModel)var3).getSize();
  475.  
  476.          for(int var5 = 0; var5 < var4; ++var5) {
  477.             Option var6 = (Option)((DefaultListModel)var3).getElementAt(var5);
  478.             this.writeOption(var6);
  479.          }
  480.       } else if (var2 instanceof OptionComboBoxModel) {
  481.          OptionComboBoxModel var7 = (OptionComboBoxModel)var2;
  482.          int var8 = ((DefaultComboBoxModel)var7).getSize();
  483.  
  484.          for(int var9 = 0; var9 < var8; ++var9) {
  485.             Option var10 = (Option)((DefaultComboBoxModel)var7).getElementAt(var9);
  486.             this.writeOption(var10);
  487.          }
  488.       }
  489.  
  490.       this.decrIndent();
  491.    }
  492.  
  493.    protected void setIndentSpace(int var1) {
  494.       this.indentSpace = var1;
  495.    }
  496.  
  497.    protected void setLineLength(int var1) {
  498.       this.maxLineLength = var1;
  499.    }
  500.  
  501.    protected void startTag(Element var1) throws IOException, BadLocationException {
  502.       if (!this.synthesizedElement(var1)) {
  503.          AttributeSet var2 = var1.getAttributes();
  504.          Object var3 = var2.getAttribute(StyleConstants.NameAttribute);
  505.          HTML.Tag var4;
  506.          if (var3 instanceof HTML.Tag) {
  507.             var4 = (HTML.Tag)var3;
  508.          } else {
  509.             var4 = null;
  510.          }
  511.  
  512.          if (var4 == Tag.PRE) {
  513.             this.inPre = true;
  514.             this.preEndOffset = var1.getEndOffset();
  515.          }
  516.  
  517.          this.closeOutUnwantedEmbeddedTags(var2);
  518.          if (this.inContent) {
  519.             this.writeNewline();
  520.             this.inContent = false;
  521.             this.newlineOutputed = false;
  522.          }
  523.  
  524.          if (this.completeDoc && var4 == Tag.BODY && !this.wroteHead) {
  525.             this.wroteHead = true;
  526.             this.indent();
  527.             this.write("<head>");
  528.             this.writeNewline();
  529.             this.incrIndent();
  530.             this.writeStyles(((HTMLDocument)((AbstractWriter)this).getDocument()).getStyleSheet());
  531.             this.decrIndent();
  532.             this.writeNewline();
  533.             this.indent();
  534.             this.write("</head>");
  535.             this.writeNewline();
  536.          }
  537.  
  538.          this.indent();
  539.          this.write('<');
  540.          this.write(var1.getName());
  541.          this.writeAttributes(var2);
  542.          this.write('>');
  543.          if (var4 != Tag.PRE) {
  544.             this.writeNewline();
  545.          }
  546.  
  547.          if (var4 == Tag.TEXTAREA) {
  548.             this.textAreaContent(var1.getAttributes());
  549.          } else if (var4 == Tag.SELECT) {
  550.             this.selectContent(var1.getAttributes());
  551.          } else if (this.completeDoc && var4 == Tag.BODY) {
  552.             this.writeMaps(((HTMLDocument)((AbstractWriter)this).getDocument()).getMaps());
  553.          } else if (var4 == Tag.HEAD) {
  554.             this.wroteHead = true;
  555.          }
  556.  
  557.       }
  558.    }
  559.  
  560.    protected boolean synthesizedElement(Element var1) {
  561.       return this.matchNameAttribute(var1.getAttributes(), Tag.IMPLIED);
  562.    }
  563.  
  564.    protected void text(Element var1) throws BadLocationException, IOException {
  565.       int var2 = Math.max(this.startOffset, var1.getStartOffset());
  566.       int var3 = Math.min(this.endOffset, var1.getEndOffset());
  567.       if (var2 < var3) {
  568.          if (this.segment == null) {
  569.             this.segment = new Segment();
  570.          }
  571.  
  572.          ((AbstractWriter)this).getDocument().getText(var2, var3 - var2, this.segment);
  573.          this.newlineOutputed = false;
  574.          if (this.segment.count > 0) {
  575.             if (this.segment.array[this.segment.offset + this.segment.count - 1] == '\n') {
  576.                this.newlineOutputed = true;
  577.             }
  578.  
  579.             if (this.inPre && var3 == this.preEndOffset) {
  580.                if (this.segment.count <= 1) {
  581.                   return;
  582.                }
  583.  
  584.                --this.segment.count;
  585.             }
  586.  
  587.             this.write(this.segment.array, this.segment.offset, this.segment.count, this.inPre ^ true, true);
  588.          }
  589.       }
  590.  
  591.    }
  592.  
  593.    protected void textAreaContent(AttributeSet var1) throws BadLocationException, IOException {
  594.       Document var2 = (Document)var1.getAttribute(StyleConstants.ModelAttribute);
  595.       if (var2 != null && var2.getLength() > 0) {
  596.          if (this.segment == null) {
  597.             this.segment = new Segment();
  598.          }
  599.  
  600.          var2.getText(0, var2.getLength(), this.segment);
  601.          if (this.segment.count > 0) {
  602.             this.inTextArea = true;
  603.             this.incrIndent();
  604.             this.indent();
  605.             this.write(this.segment.array, this.segment.offset, this.segment.count, true, true);
  606.             this.writeNewline();
  607.             this.inTextArea = false;
  608.             this.decrIndent();
  609.          }
  610.       }
  611.  
  612.    }
  613.  
  614.    public void write() throws IOException, BadLocationException {
  615.       ElementIterator var1 = ((AbstractWriter)this).getElementIterator();
  616.       Element var2 = null;
  617.       Object var3 = null;
  618.       this.wroteHead = false;
  619.       this.tempChars = null;
  620.       this.currLength = 0;
  621.       this.isLineEmpty = true;
  622.       if (this.segment == null) {
  623.          this.segment = new Segment();
  624.       }
  625.  
  626.       this.inPre = false;
  627.  
  628.       while((var6 = var1.next()) != null) {
  629.          if (((AbstractWriter)this).inRange(var6)) {
  630.             if (var2 != null) {
  631.                if (this.indentNeedsIncrementing(var2, var6)) {
  632.                   this.incrIndent();
  633.                } else if (var2.getParentElement() != var6.getParentElement()) {
  634.                   for(Element var7 = (Element)this.blockElementStack.peek(); var7 != var6.getParentElement(); var7 = (Element)this.blockElementStack.peek()) {
  635.                      this.blockElementStack.pop();
  636.                      if (!this.synthesizedElement(var7)) {
  637.                         if (!this.matchNameAttribute(var7.getAttributes(), Tag.PRE)) {
  638.                            this.decrIndent();
  639.                         }
  640.  
  641.                         this.endTag(var7);
  642.                      }
  643.                   }
  644.                } else if (var2.getParentElement() == var6.getParentElement()) {
  645.                   Element var4 = (Element)this.blockElementStack.peek();
  646.                   if (var4 == var2) {
  647.                      this.blockElementStack.pop();
  648.                      this.endTag(var4);
  649.                   }
  650.                }
  651.             }
  652.  
  653.             if (var6.isLeaf() && !this.isFormElementWithContent(var6.getAttributes())) {
  654.                this.emptyTag(var6);
  655.             } else {
  656.                this.blockElementStack.push(var6);
  657.                this.startTag(var6);
  658.             }
  659.  
  660.             var2 = var6;
  661.          }
  662.       }
  663.  
  664.       this.closeOutUnwantedEmbeddedTags((AttributeSet)null);
  665.  
  666.       while(!this.blockElementStack.empty()) {
  667.          var2 = (Element)this.blockElementStack.pop();
  668.          if (!this.synthesizedElement(var2)) {
  669.             if (!this.matchNameAttribute(var2.getAttributes(), Tag.PRE)) {
  670.                this.decrIndent();
  671.             }
  672.  
  673.             this.endTag(var2);
  674.          }
  675.       }
  676.  
  677.       if (this.completeDoc) {
  678.          this.writeAdditionalComments();
  679.       }
  680.  
  681.       this.segment.array = null;
  682.    }
  683.  
  684.    protected void write(char var1) throws IOException {
  685.       this.write(var1, false);
  686.    }
  687.  
  688.    private void write(char var1, boolean var2) throws IOException {
  689.       if (var1 == '\n') {
  690.          this.currLength = 0;
  691.          this.out.write(this.newline);
  692.          this.isLineEmpty = true;
  693.       } else {
  694.          this.isLineEmpty = false;
  695.          this.out.write(var1);
  696.          ++this.currLength;
  697.          if (var2 && this.currLength >= this.maxLineLength) {
  698.             this.writeNewline();
  699.          }
  700.       }
  701.  
  702.    }
  703.  
  704.    protected void write(String var1) throws IOException {
  705.       this.write(var1, false);
  706.    }
  707.  
  708.    private void write(String var1, boolean var2) throws IOException {
  709.       int var3 = var1.length();
  710.       if (this.tempChars == null || this.tempChars.length < var3) {
  711.          this.tempChars = new char[var3];
  712.       }
  713.  
  714.       var1.getChars(0, var3, this.tempChars, 0);
  715.       this.write(this.tempChars, 0, var3, var2, var2);
  716.    }
  717.  
  718.    private void write(char[] var1, int var2, int var3) throws IOException {
  719.       int var4 = var2;
  720.       this.isLineEmpty = false;
  721.       var3 += var2;
  722.  
  723.       for(int var5 = var2; var5 < var3; ++var5) {
  724.          switch (var1[var5]) {
  725.             case '\t':
  726.             case '\n':
  727.             case '\r':
  728.                break;
  729.             case '"':
  730.                if (var5 > var4) {
  731.                   this.out.write(var1, var4, var5 - var4);
  732.                }
  733.  
  734.                var4 = var5 + 1;
  735.                this.out.write(""");
  736.                break;
  737.             case '&':
  738.                if (var5 > var4) {
  739.                   this.out.write(var1, var4, var5 - var4);
  740.                }
  741.  
  742.                var4 = var5 + 1;
  743.                this.out.write("&");
  744.                break;
  745.             case '<':
  746.                if (var5 > var4) {
  747.                   this.out.write(var1, var4, var5 - var4);
  748.                }
  749.  
  750.                var4 = var5 + 1;
  751.                this.out.write("<");
  752.                break;
  753.             case '>':
  754.                if (var5 > var4) {
  755.                   this.out.write(var1, var4, var5 - var4);
  756.                }
  757.  
  758.                var4 = var5 + 1;
  759.                this.out.write(">");
  760.                break;
  761.             default:
  762.                if (var1[var5] < ' ' || var1[var5] > 127) {
  763.                   if (var5 > var4) {
  764.                      this.out.write(var1, var4, var5 - var4);
  765.                   }
  766.  
  767.                   var4 = var5 + 1;
  768.                   this.out.write("&#");
  769.                   this.out.write(String.valueOf(var1[var5]));
  770.                   this.out.write(59);
  771.                }
  772.          }
  773.       }
  774.  
  775.       if (var4 < var3) {
  776.          this.out.write(var1, var4, var3 - var4);
  777.       }
  778.  
  779.    }
  780.  
  781.    private void write(char[] var1, int var2, int var3, boolean var4, boolean var5) throws IOException {
  782.       if (!var4) {
  783.          int var6 = var2;
  784.          int var7 = var2 + var3;
  785.  
  786.          for(int var8 = this.indexOf(var1, '\n', var2, var7); var8 != -1; var8 = this.indexOf(var1, '\n', var6, var7)) {
  787.             if (var8 > var6) {
  788.                if (var5) {
  789.                   this.write(var1, var6, var8 - var6);
  790.                } else {
  791.                   this.out.write(var1, var6, var8 - var6);
  792.                }
  793.             }
  794.  
  795.             this.writeNewline();
  796.             var6 = var8 + 1;
  797.          }
  798.  
  799.          if (var6 < var7) {
  800.             this.currLength += var7 - var6;
  801.             if (var5) {
  802.                this.write(var1, var6, var7 - var6);
  803.             } else {
  804.                this.out.write(var1, var6, var7 - var6);
  805.             }
  806.          }
  807.       } else {
  808.          int var13 = var2;
  809.          int var14 = var2 + var3;
  810.          if (this.currLength >= this.maxLineLength && !this.isLineEmpty) {
  811.             this.writeNewline();
  812.          }
  813.  
  814.          while(var13 < var14) {
  815.             int var15 = this.indexOf(var1, '\n', var13, var14);
  816.             boolean var9 = false;
  817.             if (var15 != -1 && this.currLength + (var15 - var13) < this.maxLineLength) {
  818.                if (var15 > var13) {
  819.                   this.write(var1, var13, var15 - var13);
  820.                }
  821.  
  822.                var13 = var15 + 1;
  823.                var9 = true;
  824.             } else if (var15 == -1 && this.currLength + (var14 - var13) < this.maxLineLength) {
  825.                if (var14 > var13) {
  826.                   this.write(var1, var13, var14 - var13);
  827.                }
  828.  
  829.                this.currLength += var14 - var13;
  830.                var13 = var14;
  831.             } else {
  832.                int var10 = -1;
  833.                int var11 = Math.min(var14 - var13, this.maxLineLength - this.currLength - 1);
  834.  
  835.                for(int var12 = 0; var12 < var11; ++var12) {
  836.                   if (Character.isWhitespace(var1[var12 + var13])) {
  837.                      var10 = var12;
  838.                   }
  839.                }
  840.  
  841.                if (var10 != -1) {
  842.                   var10 += var13 + 1;
  843.                   this.write(var1, var13, var10 - var13);
  844.                   var13 = var10;
  845.                } else if (this.isLineEmpty) {
  846.                   int var20 = Math.max(0, var11);
  847.  
  848.                   for(int var19 = var14 - var13; var20 < var19; ++var20) {
  849.                      if (Character.isWhitespace(var1[var20 + var13])) {
  850.                         var10 = var20;
  851.                         break;
  852.                      }
  853.                   }
  854.  
  855.                   if (var10 == -1) {
  856.                      this.write(var1, var13, var14 - var13);
  857.                      var10 = var14;
  858.                   } else {
  859.                      var10 += var13;
  860.                      if (var1[var10] == '\n') {
  861.                         this.write(var1, var13, var10++ - var13);
  862.                      } else {
  863.                         ++var10;
  864.                         this.write(var1, var13, var10 - var13);
  865.                      }
  866.                   }
  867.  
  868.                   var13 = var10;
  869.                }
  870.  
  871.                var9 = true;
  872.             }
  873.  
  874.             if (var9 || var13 < var14) {
  875.                this.writeNewline();
  876.                if (var13 < var14) {
  877.                   this.indent();
  878.                }
  879.             }
  880.          }
  881.       }
  882.  
  883.    }
  884.  
  885.    void writeAdditionalComments() throws IOException {
  886.       Object var1 = ((AbstractWriter)this).getDocument().getProperty("AdditionalComments");
  887.       if (var1 instanceof Vector) {
  888.          Vector var2 = (Vector)var1;
  889.          int var3 = 0;
  890.  
  891.          for(int var4 = var2.size(); var3 < var4; ++var3) {
  892.             this.writeComment(var2.elementAt(var3).toString());
  893.          }
  894.       }
  895.  
  896.    }
  897.  
  898.    protected void writeAttributes(AttributeSet var1) throws IOException {
  899.       this.convAttr.removeAttributes(this.convAttr);
  900.       convertToHTML32(var1, this.convAttr);
  901.       Enumeration var2 = this.convAttr.getAttributeNames();
  902.  
  903.       while(var2.hasMoreElements()) {
  904.          Object var3 = var2.nextElement();
  905.          if (!(var3 instanceof HTML.Tag) && !(var3 instanceof StyleConstants) && var3 != Attribute.ENDTAG) {
  906.             this.write(" " + var3 + "=\"" + this.convAttr.getAttribute(var3) + "\"");
  907.          }
  908.       }
  909.  
  910.    }
  911.  
  912.    void writeComment(String var1) throws IOException {
  913.       this.write("<!--");
  914.       if (var1 != null) {
  915.          this.write(var1);
  916.       }
  917.  
  918.       this.write("-->");
  919.       this.writeNewline();
  920.    }
  921.  
  922.    protected void writeEmbeddedTags(AttributeSet var1) throws IOException {
  923.       var1 = this.convertToHTML(var1, this.oConvAttr);
  924.       Enumeration var2 = var1.getAttributeNames();
  925.  
  926.       while(var2.hasMoreElements()) {
  927.          Object var3 = var2.nextElement();
  928.          if (var3 instanceof HTML.Tag) {
  929.             HTML.Tag var4 = (HTML.Tag)var3;
  930.             if (var4 != Tag.FORM && !this.tags.contains(var4)) {
  931.                this.write('<');
  932.                this.write(var4.toString());
  933.                Object var5 = var1.getAttribute(var4);
  934.                if (var5 != null && var5 instanceof AttributeSet) {
  935.                   this.writeAttributes((AttributeSet)var5);
  936.                }
  937.  
  938.                this.write('>');
  939.                this.tags.addElement(var4);
  940.                this.tagValues.addElement(var5);
  941.             }
  942.          }
  943.       }
  944.  
  945.    }
  946.  
  947.    void writeMaps(Enumeration var1) throws IOException {
  948.       if (var1 != null) {
  949.          while(var1.hasMoreElements()) {
  950.             Map var2 = (Map)var1.nextElement();
  951.             String var3 = var2.getName();
  952.             this.incrIndent();
  953.             this.indent();
  954.             this.write("<map");
  955.             if (var3 != null) {
  956.                this.write(" name=\"");
  957.                this.write(var3);
  958.                this.write("\">");
  959.             } else {
  960.                this.write('>');
  961.             }
  962.  
  963.             this.writeNewline();
  964.             this.incrIndent();
  965.             AttributeSet[] var4 = var2.getAreas();
  966.             if (var4 != null) {
  967.                int var5 = 0;
  968.  
  969.                for(int var6 = var4.length; var5 < var6; ++var5) {
  970.                   this.indent();
  971.                   this.write("<area");
  972.                   this.writeAttributes(var4[var5]);
  973.                   this.write("></area>");
  974.                   this.writeNewline();
  975.                }
  976.             }
  977.  
  978.             this.decrIndent();
  979.             this.indent();
  980.             this.write("</map>");
  981.             this.writeNewline();
  982.             this.decrIndent();
  983.          }
  984.       }
  985.  
  986.    }
  987.  
  988.    private void writeNewline() throws IOException {
  989.       this.out.write(this.newline);
  990.       this.isLineEmpty = true;
  991.       this.currLength = 0;
  992.    }
  993.  
  994.    protected void writeOption(Option var1) throws IOException {
  995.       this.indent();
  996.       this.write('<');
  997.       this.write("option ");
  998.       if (var1.getValue() != null) {
  999.          this.write("value=" + var1.getValue());
  1000.       }
  1001.  
  1002.       if (var1.isSelected()) {
  1003.          this.write(" selected");
  1004.       }
  1005.  
  1006.       this.write('>');
  1007.       if (var1.getLabel() != null) {
  1008.          this.write(var1.getLabel());
  1009.       }
  1010.  
  1011.       this.writeNewline();
  1012.    }
  1013.  
  1014.    boolean writeStyle(String var1, Style var2, boolean var3) throws IOException {
  1015.       boolean var4 = false;
  1016.       Enumeration var5 = var2.getAttributeNames();
  1017.       if (var5 != null) {
  1018.          while(var5.hasMoreElements()) {
  1019.             Object var6 = var5.nextElement();
  1020.             if (var6 instanceof CSS.Attribute) {
  1021.                String var7 = var2.getAttribute(var6).toString();
  1022.                if (var7 != null) {
  1023.                   if (!var3) {
  1024.                      this.writeStyleStartTag();
  1025.                      var3 = true;
  1026.                   }
  1027.  
  1028.                   if (!var4) {
  1029.                      var4 = true;
  1030.                      this.indent();
  1031.                      this.write(var1);
  1032.                      this.write(" {");
  1033.                   } else {
  1034.                      this.write(";");
  1035.                   }
  1036.  
  1037.                   this.write(' ');
  1038.                   this.write(var6.toString());
  1039.                   this.write(": ");
  1040.                   this.write(var7);
  1041.                }
  1042.             }
  1043.          }
  1044.       }
  1045.  
  1046.       if (var4) {
  1047.          this.write(" }");
  1048.          this.writeNewline();
  1049.       }
  1050.  
  1051.       return var4;
  1052.    }
  1053.  
  1054.    void writeStyleEndTag() throws IOException {
  1055.       this.decrIndent();
  1056.       this.indent();
  1057.       this.write("-->");
  1058.       this.writeNewline();
  1059.       this.decrIndent();
  1060.       this.indent();
  1061.       this.write("</style>");
  1062.       this.writeNewline();
  1063.       this.indent();
  1064.    }
  1065.  
  1066.    void writeStyleStartTag() throws IOException {
  1067.       this.indent();
  1068.       this.write("<style type=\"text/css\">");
  1069.       this.incrIndent();
  1070.       this.writeNewline();
  1071.       this.indent();
  1072.       this.write("<!--");
  1073.       this.incrIndent();
  1074.       this.writeNewline();
  1075.    }
  1076.  
  1077.    void writeStyles(StyleSheet var1) throws IOException {
  1078.       if (var1 != null) {
  1079.          Enumeration var2 = ((StyleContext)var1).getStyleNames();
  1080.          if (var2 != null) {
  1081.             boolean var3 = false;
  1082.  
  1083.             while(var2.hasMoreElements()) {
  1084.                String var4 = (String)var2.nextElement();
  1085.                if (!"default".equals(var4) && this.writeStyle(var4, ((StyleContext)var1).getStyle(var4), var3)) {
  1086.                   var3 = true;
  1087.                }
  1088.             }
  1089.  
  1090.             if (var3) {
  1091.                this.writeStyleEndTag();
  1092.             }
  1093.          }
  1094.       }
  1095.  
  1096.    }
  1097. }
  1098.